﻿using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using LanhuFx.Services.Model.Dto;
using LanhuFx.Services.Model.View;
using LanhuFx.Context.PgSql.ResourcesModels;
using LanhuFx.Identity;

namespace LanhuFx.Services
{
    public class PermissionService
    {
        private readonly LanhuFxContext _Context;
        private readonly IMapper _mapper;
        private readonly TokenService _tokenService;
        public PermissionService(LanhuFxContext arg_Context
            , IMapper arg_mapper
            , TokenService arg_tokenService)
        {
            _Context = arg_Context;
            _tokenService = arg_tokenService;
            _mapper = arg_mapper;
        }

        /// <summary>
        /// 设置角色权限
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public string SetRolePermission(Dto_RolePermission arg)
        {
            var session = _tokenService.GetToken();
            var data = _Context.IdentityRolepermissions.Where(c => c.Roleid == arg.RoleId);

            if (data.Any())
            {
                _Context.IdentityRolepermissions.RemoveRange(data);
            }

            arg.Permission.ForEach(x =>
            {
                _Context.IdentityRolepermissions.Add(new IdentityRolepermissions
                {
                    Createat = DateTime.Now,
                    Id = Guid.NewGuid(),
                    Permissiontype = x.PermissionType,
                    Roleid = arg.RoleId,
                    Promissionid = x.PromissionId,
                    Teamid = session.TeamId
                });
            });
            _Context.SaveChanges();
            return "设置成功";
        }

        public Dictionary<string, List<View_PermissionSetting>> GetPermissionSetting()
        {
            //层级1:查找所有根节点 IsRoot
            //2  加载所有根节点的叶子结点即功能模块权限（eg 团队、人员管理）
            //3  根据模块下的权限Type 字段  分组查询出该模块有哪些操作（增改/删/查）
            //RETURn
            Dictionary<string, List<View_PermissionSetting>> result = new Dictionary<string, List<View_PermissionSetting>>();
            var _rs = _Context.IdentityPermissionsetting.IgnoreQueryFilters().ToList();
            var root = _rs.Where(c => c.Isroot[0]).ToList();
            if (root.Any())
            {
                foreach (var root_item in root)
                {
                    var children = _rs.Where(c => c.Parentid == root_item.Id).ToList();
                    if (children.Any())
                    {
                        var permission_items = children.Select(c => new View_PermissionSetting
                        {
                            Id = Guid.NewGuid(),
                            Name = c.Name,
                            PermissionType = c.Permissiontype
                        }).ToList();
                        result.Add(root_item.Name, permission_items);
                    }
                };
                return result;
            }
            return null;
        }

        public List<View_UserPermission> GetUserPermission()
        {
            var UserId = _tokenService.GetToken().UserId;

            if (UserId == null)
                throw new ResponseException(ResponseStateCdode.error, "未登录或已过期");

            return GetUserPermission(UserId.Value);
        }

        public List<string> GetUserRole(Guid userId)
        {
            var rs_role = _Context.IdentityUserrole.IgnoreQueryFilters().Where(c => c.Userid == userId).Select(c => c.Roleid);
            return _Context.IdentityRole.IgnoreQueryFilters().Where(c => rs_role.Contains(c.Id)).Select(c => c.Name).ToList();
        }

        /// <summary>
        /// 获取某用户所有权限
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<View_UserPermission> GetUserPermission(Guid userId)
        {
            //if (userId == null)
            //{
            //    var session = _tokenService.GetToken();
            //    userId = userId ?? session.UserId;
            //}

            var data = _Context.IdentityPermissionsetting.IgnoreQueryFilters().ProjectTo<View_PermissionUser>(_mapper.ConfigurationProvider).ToList();

            var userdata = _Context.IdentityUserpermissions.IgnoreQueryFilters().Include(c => c.Promission)
                .Where(c => c.Userid == userId)
                .Select(o => new View_UserPermission()
                {
                    Id = o.Promission.Id,
                    Name = o.Promission.Name,
                    PermissionType = o.Permissiontype
                }).ToList();

            if (userdata != null && userdata.Count > 0)
            {
                Dictionary<string, View_UserPermission> item_dic = new Dictionary<string, View_UserPermission>();

                userdata.ForEach(item =>
                {
                    if (item.PermissionType == null)
                        item.PermissionType = 0;

                    if (!item_dic.ContainsKey(item.Name))
                    {
                        item_dic.Add(item.Name, item);
                    }
                    else
                    {
                        item_dic[item.Name].PermissionType = (item_dic[item.Name].PermissionType | item.PermissionType);
                    }
                });

                data.ForEach(item =>
                {
                    if (item_dic.ContainsKey(item.Name))
                    {
                        if (item_dic[item.Name].PermissionType == 0)
                        {
                            item.IsProhibit = true;
                            item.PermissionType = 0;
                        }
                        else
                        {
                            item.IsProhibit = false;
                            item.PermissionType = item_dic[item.Name].PermissionType;
                        }
                    }
                });
            }

            var role_rs = _Context.IdentityUserrole.IgnoreQueryFilters().Where(o => o.Userid == userId).Select(o => o.Roleid);

            userdata = _Context.IdentityRolepermissions.IgnoreQueryFilters().Where(o => o.Roleid != null && role_rs.Contains(o.Roleid.Value))
                .ProjectTo<View_UserPermission>(_mapper.ConfigurationProvider).ToList();

            if (userdata != null && userdata.Count > 0)
            {
                Dictionary<string, View_UserPermission> item_dic = new Dictionary<string, View_UserPermission>();
                userdata.ForEach(item =>
                {
                    if (item.PermissionType == null)
                        item.PermissionType = 0;

                    if (!item_dic.ContainsKey(item.Name))
                    {
                        item_dic.Add(item.Name, item);
                    }
                    else
                    {
                        item_dic[item.Name].PermissionType = (item_dic[item.Name].PermissionType | item.PermissionType);
                    }

                });

                data.ForEach(item =>
                {
                    if (!item.IsProhibit)
                    {
                        if (item_dic.ContainsKey(item.Name))
                        {
                            item.PermissionType = item_dic[item.Name].PermissionType | item.PermissionType;
                        }
                    }
                });
            }

            return data.Select(o => new View_UserPermission()
            {
                Id = o.Id,
                Name = o.Name,
                PermissionType = o.PermissionType
            }).ToList();
        }

        /// <summary>
        /// 分角色获取权限数据
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public List<View_UserPermission> GetRolePermission(Guid role)
        {
            //var List_Modular = _Interface_CoreSettingService.SeachBySeachKey("MainMenu").Select(o => o.Name).ToList();

            List<string> List_Modular = new List<string>();

            var data = _Context.IdentityPermissionsetting.Where(o => List_Modular.Contains(o.Modular)).ProjectTo<View_PermissionUser>(_mapper.ConfigurationProvider).ToList();

            var userdata = _Context.IdentityRolepermissions.Where(o => o.Roleid != null && o.Roleid == role)
                .ProjectTo<View_UserPermission>(_mapper.ConfigurationProvider).ToList();

            if (userdata != null && userdata.Count > 0)
            {
                Dictionary<string, View_UserPermission> item_dic = new Dictionary<string, View_UserPermission>();
                userdata.ForEach(item =>
                {
                    if (!string.IsNullOrEmpty(item.Name))
                    {
                        if (!item_dic.ContainsKey(item.Name))
                        {
                            item_dic.Add(item.Name, item);
                        }
                        else
                        {
                            item_dic[item.Name].PermissionType = (item_dic[item.Name].PermissionType | (item.PermissionType == null ? 0 : item.PermissionType));
                        }

                        item_dic[item.Name].PermissionType = (item_dic[item.Name].PermissionType == null ? 0 : item_dic[item.Name].PermissionType);
                    }
                });

                data.ForEach(item =>
                {
                    if (!string.IsNullOrEmpty(item.Name) && !item.IsProhibit)
                    {
                        if (item_dic.ContainsKey(item.Name))
                        {
                            item.PermissionType = item_dic[item.Name].PermissionType | (item.PermissionType == null ? 0 : item.PermissionType);
                        }
                    }
                });
            }

            return data.Select(o => new View_UserPermission()
            {
                Id = o.Id,
                Name = o.Name,
                PermissionType = o.PermissionType,
                PermissionType_Setting = o.PermissionType_Setting,
                SortValue = o.SortValue,
                Modular = o.Modular
            }).OrderBy(o => o.SortValue).ToList();
        }

        /// <summary>
        /// 分局角色获取权限数据(分组)
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public Dictionary<string, List<View_UserPermission>> ByGetRolePermission(Guid role)
        {
            var list = GetRolePermission(role);

            Dictionary<string, List<View_UserPermission>> data = new Dictionary<string, List<View_UserPermission>>();

            list.GroupBy(o => o.Modular).Select(o => new { 
                key = o.Key,
                list = o.ToList()
            })
            .ToList()
            .ForEach(o => {
                data.Add(o.key, o.list);
            });

            return data;
        }

        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<View_UserPermission> ListUserPermission(Guid userId)
        {
            var data = _Context.IdentityUserpermissions.Where(c => c.Userid == userId).ToList();
            if (!data.Any())
            {
                throw new ResponseException(ResponseStateCdode.error, "该用户权限不存在");
            }

            var userList = new List<View_UserPermission>();
            foreach (var item in data)
            {
                var users = _Context.IdentityPermissionsetting.FirstOrDefault(c => c.Id == item.Promissionid);

                if (users != null)
                {
                    var user = new View_UserPermission
                    {
                        Id = users.Id,
                        Name = users.Name,
                        PermissionType = item.Permissiontype
                    };
                    userList.Add(user);
                }
            }
            return userList;
        }

        /// <summary>
        /// 设置用户权限
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public string SetUserPermission(Dto_SetUserPermission arg)
        {
            var session = _tokenService.GetToken();
            var data = _Context.IdentityUserpermissions.Where(c => c.Userid == arg.UserId);
            if (data.Any())
            {
                _Context.IdentityUserpermissions.RemoveRange(data);
            }
            arg.Permission.ForEach(x =>
            {
                _Context.IdentityUserpermissions.Add(new IdentityUserpermissions
                {
                    Createat = DateTime.Now,
                    Id = Guid.NewGuid(),
                    Permissiontype = x.PermissionType,
                    Promissionid = x.PerminssionId,
                    Teamid = session.TeamId,
                    Userid = arg.UserId
                });
            });
            _Context.SaveChanges();
            return "设置成功";
        }

        #region 权限资源

        public List<View_Role> RoleAll()
        {
            return _Context.IdentityRole.ProjectTo<View_Role>(_mapper.ConfigurationProvider).ToList();
        }

        public List<View_PermissionSetting> PermissionAll()
        {
            return _Context.IdentityPermissionsetting.ProjectTo<View_PermissionSetting>(_mapper.ConfigurationProvider).ToList();
        }

        #endregion

        #region 权限

        ///// <summary>
        ///// 设置权限
        ///// </summary>
        ///// <param name="arg"></param>
        ///// <returns></returns>
        //public string SetPermission(DtoPermissionSetting arg)
        //{
        //    //给某个人赋予某个模块的某类型（增改/删/查）权限
        //    //传入该模块(团队、人员)Id     、权限类型（增改/删/查）、用户Id   
        //    //查询出该模块下所有该类型的权限赋予该用户
        //    //即完成授权流程
        //    var session = _tokenService.GetToken();

        //    var param_settings = _Context.IdentityPermissionsetting.Where(c => c.ParentId == arg.Id);

        //    #region 参数验证
        //    if (!param_settings.Any())
        //    {
        //        throw new ResponseException(ResponseStateCdode.error, $"{arg.Id}不包含{arg.OperateType}类型的权限");
        //    }
        //    #endregion

        //    var permissionIds = param_settings.Select(c => c.Id).ToList();

        //    var already_Contains = _Context.IdentityUserPermissions.Where(c => c.UserId == session.UserId && permissionIds.Contains(c.PromissionId.Value));

        //    //选择无权限时  或者选择的操作类型已经有授权数据时，取消该类型权限
        //    if (already_Contains.Any() || arg.OperateType.PermissionTypeToArray() == (int)PermissionType.None)
        //    {
        //        //如果已经存在该权限
        //        //则取消
        //        _Context.IdentityUserPermissions.RemoveRange(already_Contains);
        //    }
        //    else
        //    {
        //        //新增权限
        //        permissionIds.ForEach(x =>
        //        {
        //            _Context.IdentityUserPermissions.Add(new IdentityUserPermissions
        //            {
        //                Id = Guid.NewGuid(),
        //                CreateAt = DateTime.Now,
        //                PromissionId = x,
        //                UserId = session.UserId,
        //                PermissionType = arg.OperateType.PermissionTypeToArray()
        //            });
        //        });
        //    }
        //    _Context.SaveChanges();
        //    return "设置成功";
        //}

        //public string SetRolePermission(Dto_SetPermission arg)
        //{
        //    var roles = new List<dynamic>() { arg.RoleId };
        //    var permission = _Context.IdentityRolePermissions.FirstOrDefault(c => roles.Contains(c.RoleId));
        //    if (permission != null)
        //    {
        //        var data = EntityParameterUpdateCheck.Check(permission, arg);
        //        _Context.Update(permission);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("人员权限：{0}不存在", arg.RoleId));
        //    return "设置成功";
        //}

        ///// <summary>
        ///// 获取菜单资源列表
        ///// </summary>
        //public List<View_MenuResource> GetMenuResource(string name)
        //{
        //    var userSession = _tokenService.GetToken();
        //    var resource = _Context.MenuResource.Where(c => 1==1);
        //    if (!string.IsNullOrEmpty(name))
        //    {
        //         resource = resource.Where(c => c.Name.Contains(name));
        //    }
        //    return resource.ProjectTo<View_MenuResource>().ToList();
        //}

        ///// <summary>
        ///// 获取功能资源列表
        ///// </summary>
        //public List<View_ApiResource> GetApiResource(string name)
        //{
        //    var resource = _Context.ApiResource.Where(c=>1==1);
        //    if (!string.IsNullOrEmpty(name))
        //    {
        //        resource = resource.Where(c => c.Name.Contains(name));
        //    }
        //    return resource.ProjectTo<View_ApiResource>().ToList();
        //}

        ///// <summary>
        ///// 添加菜单资源列表
        ///// </summary>
        //public string CreateMenuResource(DtoCreateMenuResource arg)
        //{
        //    _Context.MenuResource.Add(_mapper.Map<MenuResource>(arg));
        //    //排序
        //    //IsActive
        //    //TeamId
        //    _Context.SaveChanges();
        //    return "菜单添加成功";
        //}

        ///// <summary>
        ///// 添加功能资源列表
        ///// </summary>
        //public string CreateApiResource(DtoCreateApiResource arg)
        //{
        //    _Context.ApiResource.Add(_mapper.Map<ApiResource>(arg));
        //    _Context.SaveChanges();
        //    return "功能添加成功";
        //}

        ///// <summary>
        ///// 修改菜单资源列表
        ///// </summary>
        //public string EditMenuResource(DtoMenuResource dto)
        //{
        //    var userId = new List<dynamic>() { dto.Id };
        //    var menu = _Context.MenuResource.FirstOrDefault(c => userId.Contains(c.Id));
        //    if (menu != null)
        //    {
        //        var data = EntityParameterUpdateCheck.Check(menu, dto);
        //        _Context.Update(menu);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("菜单：{0}不存在", dto.Id));
        //    return "修改成功";
        //}

        ///// <summary>
        ///// 修改功能资源列表
        ///// </summary>
        //public string EditApiResource(DtoApiResource dto)
        //{
        //    var userId = new List<dynamic>() { dto.Id };
        //    var menu = _Context.ApiResource.FirstOrDefault(c => userId.Contains(c.Id));
        //    if (menu != null)
        //    {
        //        var data = EntityParameterUpdateCheck.Check(menu, dto);
        //        _Context.Update(menu);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("功能：{0}不存在", dto.Id));
        //    return "修改成功";
        //}

        ///// <summary>
        ///// 删除菜单资源列表
        ///// </summary>
        //public string DeleteMenuResource(Guid id)
        //{
        //    var menu = _Context.MenuResource.FirstOrDefault(c => c.Id == id);
        //    //如果此菜单被赋予组或人，则不能执行删除，因为此权限生效中
        //    if (menu != null)
        //    {
        //        _Context.MenuResource.Remove(menu);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("菜单：{0}不存在", id));
        //    return "删除成功";

        //}

        ///// <summary>
        ///// 删除功能资源列表
        ///// </summary>
        //public string DeleteApiResource(Guid id)
        //{
        //    var menu = _Context.ApiResource.FirstOrDefault(c => c.Id == id);
        //    if (menu != null)
        //    {
        //        _Context.ApiResource.Remove(menu);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("功能：{0}不存在", id));
        //    return "删除成功";
        //}
        //#endregion

        //#region 权限设置

        ///// <summary>
        ///// 设置组权限
        ///// </summary>
        //public string SetGroupPermission(DtoSetGroupPermission arg)
        //{
        //    var users = new List<dynamic>() { arg.GroupId };
        //    var permission = _Context.GroupPermission.FirstOrDefault(c => users.Contains(c.GroupId));
        //    if (permission != null)
        //    {
        //        var data = EntityParameterUpdateCheck.Check(permission, arg);
        //        _Context.Update(permission);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("组权限：{0}不存在", arg.GroupId));
        //    return "设置成功";
        //}

        ///// <summary>
        ///// 设置人员权限
        ///// </summary>
        //public string SetUserPermission(DtoSetUserPermission arg)
        //{
        //    var users = new List<dynamic>() { arg.UserId };
        //    var permission = _Context.UserPermission.FirstOrDefault(c => users.Contains(c.UserId));
        //    if (permission != null)
        //    {
        //        var data = EntityParameterUpdateCheck.Check(permission, arg);
        //        _Context.Update(permission);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("人员权限：{0}不存在", arg.UserId));
        //    return "设置成功";
        //}
        ///// <summary>
        ///// 取消组权限
        ///// </summary>
        //public string CancelGroupPermission(DtoCancelGroupPermission arg)
        //{
        //    var permission = _Context.GroupPermission.FirstOrDefault(c => c.Id == arg.Id && c.GroupId == arg.GroupId);
        //    if (permission != null)
        //    {
        //        _Context.GroupPermission.Remove(permission);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("组权限：{0}或{1}不存在", arg.Id, arg.GroupId));
        //    return "取消成功";
        //}
        ///// <summary>
        ///// 取消人员权限
        ///// </summary>
        //public string CancelUserPermission(DtoCancelUserPermission arg)
        //{
        //    var permission = _Context.UserPermission.FirstOrDefault(c => c.Id == arg.Id && c.UserId == arg.UserId);
        //    if (permission != null)
        //    {
        //        _Context.UserPermission.Remove(permission);
        //        _Context.SaveChanges();
        //    }
        //    else
        //        throw new ResponseException(ResponseStateCdode.error, string.Format("人员权限：{0}或{1}不存在", arg.Id, arg.UserId));
        //    return "取消成功";
        //}

        ///// <summary>
        ///// 获取组权限
        ///// </summary>
        ///// <param name="id"></param>
        //public View_PermissionCombine GetGroupPermission(List<View_GroupPerson> arg)
        //{
        //    if (arg == null || !arg.Any())
        //    {
        //        return null;
        //    }
        //    var types = arg.Where(c => c.Type != null).GroupBy(c => c.Type);
        //    List<GroupPermission> permissions = new List<GroupPermission>();
        //    foreach (var item in types)
        //    {
        //        var limits = new string[] { item.Key, "All" };
        //        var groupIds = arg.Where(c => c.Type == item.Key).Select(c => c.GroupId);
        //        if (groupIds.Any())
        //        {
        //            var rlt = _Context.GroupPermission.Include(c => c.ApiResource).Include(c => c.MenuResource)
        //                             .Where(c => groupIds.Contains(c.GroupId) && limits.Contains(c.GroupRoleLimit))
        //                             .ToList();
        //            permissions.AddRange(rlt);
        //        }
        //    }

        //    return _mapper.Map<View_PermissionCombine>(permissions);
        //}
        ///// <summary>
        ///// 获取个人权限
        ///// </summary>
        ///// <param name="id"></param>
        //public View_PermissionCombine GetUserPermission(Guid id)
        //{
        //    var permissions = _Context.UserPermission.Include(c => c.ApiResource).Include(c => c.MenuResource)
        //        .Where(c => id == c.UserId)
        //        .ToList();
        //    return _mapper.Map<View_PermissionCombine>(permissions);
        //}
        #endregion

    }
}
